package com.chatroom.client.ui;

import com.chatroom.client.model.ChatMessage;
import com.chatroom.client.model.MessageType;

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.time.Duration;
import java.time.format.DateTimeFormatter;
import java.util.Map;

/**
 * JList 的自定义单元格渲染器，负责显示时间戳、系统消息和用户消息。
 */
public class MessageListCellRenderer extends DefaultListCellRenderer {

    private static final DateTimeFormatter FULL_DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
    private static final DateTimeFormatter TIME_ONLY_FORMATTER = DateTimeFormatter.ofPattern("HH:mm:ss");
    private static final Duration TIME_GAP_FOR_TIMESTAMP = Duration.ofMinutes(5);

    private final Map<String, ImageIcon> avatarCache;
    private final Map<String, ImageIcon> emojiCache;
    private final int AVATAR_SIZE;

    public MessageListCellRenderer(Map<String, ImageIcon> avatarCache, Map<String, ImageIcon> emojiCache, int avatarSize) {
        this.avatarCache = avatarCache;
        this.emojiCache = emojiCache;
        this.AVATAR_SIZE = avatarSize;
    }

    @Override
    public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
        ChatMessage message = (ChatMessage) value;

        // 主容器，使用Y轴的BoxLayout来垂直排列时间戳和消息体
        JPanel container = new JPanel();
        container.setLayout(new BoxLayout(container, BoxLayout.Y_AXIS));
        container.setBackground(list.getBackground());

        // --- 时间戳逻辑 ---
        boolean showTimestamp = false;
        boolean showFullDate = false;
        if (index == 0) {
            showTimestamp = true;
            showFullDate = true;
        } else {
            ChatMessage previousMessage = (ChatMessage) list.getModel().getElementAt(index - 1);
            if (!previousMessage.getTimestamp().toLocalDate().isEqual(message.getTimestamp().toLocalDate())) {
                showTimestamp = true;
                showFullDate = true;
            } else if (Duration.between(previousMessage.getTimestamp(), message.getTimestamp()).compareTo(TIME_GAP_FOR_TIMESTAMP) > 0) {
                showTimestamp = true;
            }
        }

        if (showTimestamp) {
            DateTimeFormatter formatter = showFullDate ? FULL_DATE_TIME_FORMATTER : TIME_ONLY_FORMATTER;
            JLabel timeLabel = new JLabel(message.getTimestamp().format(formatter));
            timeLabel.setFont(new Font("微软雅黑", Font.PLAIN, 12)); // 调小字号
            timeLabel.setForeground(Color.GRAY);
            timeLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
            timeLabel.setBorder(new EmptyBorder(10, 0, 5, 0));
            container.add(timeLabel);
        }

        // --- 消息体渲染 ---
        Component messageComponent;
        if (message.getType() == MessageType.SYSTEM) {
            JLabel systemLabel = new JLabel(message.getContent());
            systemLabel.setFont(new Font("微软雅黑", Font.PLAIN, 14));
            systemLabel.setForeground(Color.GRAY);
            JPanel systemPanel = new JPanel();
            systemPanel.setBackground(list.getBackground());
            systemPanel.add(systemLabel);
            messageComponent = systemPanel;
        } else {
            // 获取头像并创建MessagePanel
            ImageIcon avatar = getAvatar(message.getSender());
            messageComponent = new MessagePanel(message, list.getWidth(), avatar, emojiCache);
        }
        container.add(messageComponent);

        // 为了消除选中时的蓝色背景，我们需要自己处理
        if(isSelected) {
            container.setBackground(list.getSelectionBackground());
        }

        return container;
    }

    // 从原 Client 类中移入的头像生成逻辑
    private ImageIcon getAvatar(String name) {
        return avatarCache.computeIfAbsent(name, n -> {
            BufferedImage image = new BufferedImage(AVATAR_SIZE, AVATAR_SIZE, BufferedImage.TYPE_INT_RGB);
            Graphics2D g2d = image.createGraphics();
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

            int hash = n.hashCode();
            Color color = new Color((hash & 0xFF0000) >> 16, (hash & 0x00FF00) >> 8, (hash & 0x0000FF));
            g2d.setColor(color);
            g2d.fillRect(0, 0, AVATAR_SIZE, AVATAR_SIZE);

            g2d.setColor(Color.WHITE);
            g2d.setFont(new Font("微软雅黑", Font.BOLD, 20));
            FontMetrics fm = g2d.getFontMetrics();
            String initial = n.substring(0, 1).toUpperCase();
            int x = (AVATAR_SIZE - fm.stringWidth(initial)) / 2;
            int y = (fm.getAscent() + (AVATAR_SIZE - (fm.getAscent() + fm.getDescent())) / 2);
            g2d.drawString(initial, x, y);
            g2d.dispose();
            return new ImageIcon(image);
        });
    }
}
